// @ts-ignore
/* eslint-disable */
import { message } from "antd";
import TokenManager from "@/token";
import { request } from "@umijs/max";
import type { API } from "@/types/api";
import { postRefreshToken } from "@/services/core/api";
// import { resetComponent } from "@ant-design/pro-components";
// import baseURL from "public/config.js";

// 公共Token验证方法
async function validateToken(navigate: any): Promise<boolean> {
    const accessToken = TokenManager.getAccessToken();
    const isInvalidAccessToken = [
        null,
        "",
        " [object Promise]",
        "null",
    ].includes(accessToken);
    if (!isInvalidAccessToken) {
        const refreshToken = TokenManager.getRefreshToken();
        const isInvalidRefreshToken = [
            null,
            "",
            " [object Promise]",
            "null",
        ].includes(refreshToken);
        if (isInvalidRefreshToken) {
            console.log("refresh_token过期！");
            // navigate("/login");
            window.location.reload();
            await postRefreshToken(navigate);
        }
        return false;
    }
    return true;
}

export async function postLookFileContext(
    body: API.PostJarContext,
    stype: string,
    node_id: string,
    navigate?: any,
): Promise<any> {
    await validateToken(navigate);
    console.log("node_id", node_id);
    return await request<API.PostJarContextResult>(
        `/api/apps/hosting/file_editor/look?stype=${stype}` +
            "&node_id=" +
            node_id,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
            data: body,
        },
    )
        .then((res) => {
            return res;
        })
        .catch(async (err: any) => {
            if (err.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postLookFileContext(body, node_id, navigate);
            } else {
                message.error(err.response.data.message);
                return err.response.data;
            }
        });
}

/** POST /api/apps/hosting/all_apps */
export async function postAllApps(navigate: any): Promise<any> {
    let result;
    await validateToken(navigate);
    return await request<API.PostAllAppsResult>("/api/apps/hosting/all_apps", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            Authorization: "Bearer " + TokenManager.getAccessToken(),
        },
    })
        .then((res: API.PostAllAppsResult) => {
            return res;
        })
        .catch(async (error: any) => {
            console.log("error", error);
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postAllApps(navigate);
            }
            result = error.response.data;
        });
}

/** POST /api/apps/hosting/control */
export async function postAppControl(
    body: API.PostAppControlParam,
    stype: string,
    node_id: string,
    navigate: any,
): Promise<API.PostAppControlResult | null> {
    await validateToken(navigate);
    return await request<API.PostAllAppsResult>(
        "/api/apps/hosting/control?stype=" + stype + "&node_id=" + node_id,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
            data: body,
        },
    )
        .then((res: API.PostAllAppsResult) => {
            return res;
        })
        .catch(async (error: any) => {
            console.log("error", error);
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postAppControl(body, stype, node_id, navigate);
            }
            return error.response.data;
        });
}

export async function postRegisterApp(
    body: API.PostRegisterAppParam,
    stype: "java" | "web",
    node_id: string,
    navigate: any,
): Promise<API.PostRegisterAppResult> {
    await validateToken(navigate);
    return await request<API.PostRegisterAppResult>(
        "/api/apps/hosting/register?stype=" + stype + "&node_id=" + node_id,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
            data: body,
        },
    )
        .then((res: API.PostRegisterAppResult) => {
            return res;
        })
        .catch(async (error: any) => {
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postRegisterApp(body, stype, node_id, navigate);
            } else {
                message.error(error.response.data.message);
                return error.response.data;
            }
        });
}

export async function postAllStypes(
    navigate: any,
): Promise<API.PostAllStypesResult> {
    await validateToken(navigate);
    return await request<API.PostRegisterAppResult>(
        "/api/apps/hosting/all_stypes",
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
        },
    )
        .then((res: API.PostRegisterAppResult) => {
            return res;
        })
        .catch(async (error: any) => {
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postAllStypes(navigate);
            } else {
                message.error(error.response.data.message);
                return error.response.data;
            }
        });
}

export async function postReceiveFile(
    body: FormData,
    node_id: string,
    navigate: any,
): Promise<API.PostReceviceFileResult> {
    await validateToken(navigate);
    return await request<API.PostReceviceFileResult>(
        "/api/apps/hosting/receive_file?node_id=" + node_id,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
            data: body,
        },
    )
        .then((res: API.PostReceviceFileResult) => {
            return res;
        })
        .catch(async (error: any) => {
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postReceiveFile(body, node_id, navigate);
            } else {
                message.error(error.response.data.message);
                return error.response.data;
            }
        });
}

export async function postAppInfo(
    body: API.PostAppInfoParam,
    stype: string,
    node_id: string,
    navigate: any,
): Promise<API.PostAppInfoResult> {
    await validateToken(navigate);
    return await request<API.PostAppInfoResult>(
        `/api/apps/hosting/info?stype=${stype}` + "&node_id=" + node_id,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
            data: body,
        },
    )
        .then((res: API.PostAppInfoResult) => {
            return res;
        })
        .catch(async (error: any) => {
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postAppInfo(body, stype, node_id, navigate);
            } else {
                message.error(error.response.data.message);
                return error.response.data;
            }
        });
}

/**
 * 获取实时日志流
 */
interface SSEClient {
    close: () => void;
}

export async function getRealogSSE(
    appId: string,
    stype: string,
    navigate: any,
    onMessage: (data: string) => void,
    onError?: (error: Error) => void,
): Promise<SSEClient | null> {
    try {
        await validateToken(navigate);
        const url = `${API_BASE_URL}/api/apps/hosting/realog?app_id=${appId}&stype=${stype}`;
        const response = await fetch(url, {
            headers: {
                Authorization: `Bearer ${TokenManager.getAccessToken()}`,
                Accept: "text/event-stream",
            },
        });

        if (!response.ok || !response.body) {
            throw new Error(`SSE连接失败: ${response.statusText}`);
        }
        // console.log('response：', response);
        const reader = response.body.getReader();
        const decoder = new TextDecoder();
        let isClosed = false;
        (async function readStream() {
            try {
                while (!isClosed) {
                    const { done, value } = await reader.read();
                    if (done) {
                        onError?.(new Error("SSE连接已关闭"));
                        break;
                    }

                    const chunk = decoder.decode(value);
                    // 处理SSE格式数据（以\n\n分隔事件）
                    chunk.split("\n\n").forEach((event) => {
                        if (event) {
                            // 确保event以data:开头（标准SSE格式）
                            const dataPrefix = "data: ";
                            if (event.startsWith(dataPrefix)) {
                                const jsonStr = event.substring(
                                    dataPrefix.length,
                                );
                                try {
                                    const jsonData = JSON.parse(jsonStr);
                                    onMessage(jsonData);
                                } catch (error) {
                                    console.error(
                                        "Failed to parse event as JSON:",
                                        error,
                                    );
                                    onMessage(jsonStr); // 回退到原始字符串
                                }
                            } else {
                                // 处理非标准格式数据
                                onMessage(event);
                            }
                        }
                    });
                }
            } catch (err) {
                onError?.(err as Error);
            }
        })();
        return {
            close: () => {
                isClosed = true;
                reader.cancel().catch(() => {});
            },
        };
    } catch (error: any) {
        console.error("创建SSE连接失败:", error);
        // Token过期处理逻辑（根据实际需求启用）
        // if (error.response?.status === 401) {
        //   await TokenManager.refreshToken(navigate);
        //   return getRealogSSE(appId, stype, navigate, onMessage, onError);
        // }
        onError?.(error);
        return error;
    }
}

export async function postRealogSSEStop(
    appId: string,
    stype: string,
    node_id: string,
    navigate: any,
): Promise<API.PostAppInfoResult> {
    await validateToken(navigate);
    return await request<API.PostAppInfoResult>(
        `/api/apps/hosting/stop_realog?stype=${stype}` + "&node_id=" + node_id,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
            data: {
                app_id: appId,
            },
        },
    )
        .then((res: API.PostAppInfoResult) => {
            return res;
        })
        .catch(async (error: any) => {
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postRealogSSEStop(appId, stype, node_id, navigate);
            } else {
                message.error(error.response.data.message);
                return error.response.data;
            }
        });
}

export async function postAppRemove(
    appId: string,
    stype: string,
    node_id: string,
    navigate: any,
): Promise<API.PostAppRemoveResult> {
    await validateToken(navigate);
    return await request<API.PostAppRemoveResult>(
        `/api/apps/hosting/remove?stype=${stype}` + "&node_id=" + node_id,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
            data: {
                app_id: appId,
            },
        },
    )
        .then((res: API.PostAppRemoveResult) => {
            return res;
        })
        .catch(async (error: any) => {
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postRealogSSEStop(appId, stype, node_id, navigate);
            } else {
                message.error(error.response.data.message);
                return error.response.data;
            }
        });
}

export async function postFileChange(
    body: {
        app_id: string;
        path: string;
        value: string;
    },
    stype: string,
    node_id: string,
    navigate: any,
): Promise<API.PostAppRemoveResult> {
    await validateToken(navigate);
    return await request<API.PostAppRemoveResult>(
        `/api/apps/hosting/file_editor/change?stype=${stype}` +
            "&node_id=" +
            node_id,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
            data: body,
        },
    )
        .then((res: API.PostAppRemoveResult) => {
            return res;
        })
        .catch(async (error: any) => {
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postFileChange(body, stype, node_id, navigate);
            } else {
                message.error(error.response.data.message);
                return error.response.data;
            }
        });
}

export async function postDeployApp(
    body: API.PostDeployAppParam,
    stype: "java" | "static",
    navigate: any,
): Promise<API.PostDeployAppResult> {
    await validateToken(navigate);
    return await request<API.PostDeployAppResult>(
        "/api/apps/hosting/deploy?stype=" + stype,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
            data: body,
        },
    )
        .then((res: API.PostDeployAppResult) => {
            return res;
        })
        .catch(async (error: any) => {
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postDeployApp(body, stype, navigate);
            } else {
                message.error(error.response.data.message);
                return error.response.data;
            }
        });
}

export async function postDownloadFile(
    app_id: string,
    stype: string,
    node_id: string,
    navigate: any,
): Promise<boolean> {
    try {
        await validateToken(navigate);
        const token = TokenManager.getAccessToken();
        
        // 使用fetch API发送带Authorization头的请求
        const response = await fetch(
            `${API_BASE_URL}/api/apps/hosting/download_file?stype=${stype}&app_id=${app_id}&node_id=${node_id}`,
            {
                method: 'GET',
                headers: {
                    'Authorization': `Bearer ${token}`,
                },
            }
        );

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        // 从Content-Disposition头获取文件名
        let filename = 'download';
        const contentDisposition = response.headers.get('Content-Disposition');
        if (contentDisposition) {
            // 匹配 filename*= 格式 (RFC 5987 标准)
            const utf8FilenameMatch = contentDisposition.match(/filename\*="?UTF-8''([^"]+)"?/i);
            if (utf8FilenameMatch && utf8FilenameMatch[1]) {
                try {
                    filename = decodeURIComponent(utf8FilenameMatch[1]);
                } catch (e) {
                    filename = utf8FilenameMatch[1];
                }
            } else {
                // 匹配 filename= 格式
                const filenameMatch = contentDisposition.match(/filename="?([^"]+)"?/);
                if (filenameMatch && filenameMatch[1]) {
                    filename = filenameMatch[1];
                }
            }
        }

        // 创建一个隐藏的链接元素来处理文件下载
        const blob = await response.blob();
        const url = window.URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = filename;
        link.style.display = 'none';
        document.body.appendChild(link);
        link.click();
        
        // 清理创建的元素和URL
        setTimeout(() => {
            document.body.removeChild(link);
            window.URL.revokeObjectURL(url);
        }, 30000);
        
        return true;
    } catch (error) {
        console.error("下载失败:", error);
        return false;
    }
}

export async function postNgxTemp(
    node_id: string,
    navigate: any,
): Promise<API.PostNgxTempResult> {
    await validateToken(navigate);
    return await request<API.PostNgxTempResult>(
        "/api/apps/hosting/static/ngx_conf?node_id=" + node_id,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
        },
    )
        .then((res: API.PostNgxTempResult) => {
            return res;
        })
        .catch(async (error: any) => {
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postNgxTemp(node_id, navigate);
            } else {
                message.error(error.response.data.message);
                return error.response.data;
            }
        });
}

export async function postRollBack(
    body: API.PostRollBackParam,
    stype: string,
    node_id: string,
    navigate: any,
): Promise<API.PostRollBackResult> {
    await validateToken(navigate);
    return await request<API.PostNgxTempResult>(
        `/api/apps/hosting/rollback?stype=${stype}` + "&node_id=" + node_id,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
            data: body,
        },
    )
        .then((res: API.PostNgxTempResult) => {
            return res;
        })
        .catch(async (error: any) => {
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postRollBack(body, stype, node_id, navigate);
            } else {
                message.error(error.response.data.message);
                return error.response.data;
            }
        });
}

export async function postRollBackRemove(
    body: API.PostRollBackRemoveParam,
    stype: string,
    node_id: string,
    navigate: any,
): Promise<API.PostRollBackRemoveResult> {
    await validateToken(navigate);
    return await request<API.PostRollBackRemoveParam>(
        `/api/apps/hosting/rollback/remove?stype=${stype}` +
            "&node_id=" +
            node_id,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
            data: body,
        },
    )
        .then((res: any) => {
            return res;
        })
        .catch(async (error: any) => {
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postRollBackRemove(body, stype, node_id, navigate);
            } else {
                message.error(error.response.data.message);
                return error.response.data;
            }
        });
}

export async function postRealog(
    body: API.PostRealogParam,
    stype: string,
    node_id: string,
    navigate: any,
): Promise<API.PostRealogResult> {
    await validateToken(navigate);
    return await request<API.PostRealogResult>(
        `/api/apps/hosting/realog?stype=${stype}` +
            `&node_id=${node_id}`,
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + TokenManager.getAccessToken(),
            },
            data: body,
        },
    )
        .then((res: API.PostRealogResult) => {
            return res;
        })
        .catch(async (error: any) => {
            if (error.response.data.status_code === "EXPIRED_TOKEN") {
                console.log("触发token刷新！");
                await postRefreshToken(navigate);
                return await postRealog(body, stype, node_id, navigate);
            } else {
                message.error(error.response.data.message);
                return error.response.data;
            }
        });
}
